home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1994 June / PC Plus Super CD coverdisc Issue 93 June 1994.iso / suprdisk / wilfpw / wordfind.bas next >
Encoding:
BASIC Source File  |  1994-05-31  |  5.2 KB  |  192 lines

  1. DEFINT A-Z
  2. DECLARE SUB QuickSort (Low%, High%)
  3. DECLARE SUB GetWordList (FileSpec$)
  4. DECLARE FUNCTION RandInt% (Lower%, Upper%)
  5. DECLARE FUNCTION BinChop (Lower%, Upper%)
  6. DIM SHARED WordList(500) AS STRING
  7. DIM SHARED NumWords%
  8. DIM SHARED Key$
  9.  
  10. CLS
  11. PRINT "Wait..."
  12. NumWords% = 0
  13. GetWordList ("WORDS.DAT")
  14. QuickSort 0, NumWords% - 1
  15.  
  16. ' Get the key phrase and display closest match
  17.  
  18. Key$ = ""
  19. DO UNTIL False
  20.     Chop% = BinChop(0, NumWords% - 1)
  21.     IF Chop% <> -1 THEN
  22.         LOCATE 23, 1
  23.         PRINT SPACE$(40)
  24.         LOCATE 23, 1
  25.         PRINT WordList(Chop%)
  26.     END IF
  27.  
  28.     LOCATE 2, 1
  29.     PRINT "Enter a word to match: "; Key$; " ";
  30.     LOCATE CSRLIN, POS(1) - 1, 1
  31.  
  32.     ' Read next character
  33.          
  34.     DO
  35.         X$ = UCASE$(INKEY$)
  36.     LOOP WHILE X$ = ""
  37.  
  38.     IF (X$ = CHR$(27)) OR (X$ = CHR$(13)) THEN
  39.         EXIT DO
  40.     ELSEIF (X$ = CHR$(8)) OR (X$ = CHR$(0) + CHR$(75)) THEN  'Backspace
  41.         IF LEN(Key$) > 0 THEN
  42.             Key$ = MID$(Key$, 1, LEN(Key$) - 1)
  43.         ELSE
  44.             ' Empty string - can't backup any more
  45.             PRINT CHR$(7)
  46.         END IF
  47.     ELSE
  48.         Key$ = Key$ + X$
  49.     END IF
  50. LOOP
  51. END
  52.  
  53. ' ============================== BinChop ===================================
  54. '   Perform a binary chop on the word list looking for the closest match.
  55. '   The word we're searching for is assumed to be in the Key$ variable.
  56. '   BinChop returns the array index of the found word.
  57. ' ============================================================================
  58. '
  59. FUNCTION BinChop (Lower%, Upper%)
  60.     DIM MidPoint AS INTEGER
  61.  
  62.     ' Firstly, make sure we're in the same ballpark
  63.     IF (Key$ < WordList(Lower%)) OR (Key$ > WordList(Upper%)) THEN
  64.         BinChop = -1
  65.         EXIT FUNCTION
  66.     END IF
  67.  
  68.     ' Now see if we've converged down to 2/3 elements
  69.     IF Upper% - Lower% <= 1 THEN
  70.         IF Key$ > WordList(Lower%) THEN
  71.             BinChop = Upper%
  72.         ELSE
  73.             BinChop = Lower%
  74.         END IF
  75.         EXIT FUNCTION
  76.     END IF
  77.  
  78.     ' Haven't converged yet - do the chop
  79.     MidPoint = Lower + ((Upper% - Lower%) / 2)
  80.     IF Key$ = WordList(MidPoint) THEN
  81.         ' What, me - Optimistic ?
  82.         BinChop = MidPoint
  83.     ELSEIF Key$ > WordList(MidPoint) THEN
  84.         BinChop = BinChop(MidPoint, Upper)
  85.     ELSE
  86.         BinChop = BinChop(Lower, MidPoint)
  87.     END IF
  88. END FUNCTION
  89.  
  90. ' ============================== GetWordList =================================
  91. '   This routine opens a file and reads up to 500 words from it into an array.
  92. '   No attempt is made to perform de-duplication of the input.
  93. ' ============================================================================
  94. '
  95. SUB GetWordList (FileSpec$)
  96.     DIM I AS INTEGER
  97.     OPEN FileSpec$ FOR INPUT AS #1
  98.     DO
  99.         LINE INPUT #1, Line$
  100.         Line$ = UCASE$(LTRIM$(RTRIM$(Line$)))
  101.  
  102.         ' Split the line into individual words '
  103.  
  104.         DO WHILE LEN(Line$) > 0
  105.             I = INSTR(Line$, " ")
  106.             IF I > 0 THEN
  107.                 WordList(NumWords%) = LEFT$(Line$, I - 1)
  108.                 Line$ = RIGHT$(Line$, LEN(Line$) - I)
  109.             ELSE
  110.                 WordList(NumWords%) = Line$
  111.                 Line$ = ""
  112.             END IF
  113.  
  114.             NumWords% = NumWords% + 1
  115.             IF NumWords% = 500 THEN
  116.                 CLOSE #1
  117.                 EXIT SUB
  118.             END IF
  119.         LOOP
  120.     LOOP UNTIL EOF(1)
  121.     CLOSE #1
  122. END SUB
  123.  
  124. ' ============================== QuickSort ===================================
  125. '   QuickSort works by picking a random "pivot" element in then moving every
  126. '   element that is bigger to one side of the pivot, and every element that
  127. '   is smaller to the other side.  QuickSort is then called recursively with
  128. '   the two subdivisions created by the pivot.  Once the number of elements
  129. '   in a subdivision reaches two, the recursive calls end and the array is sorted.
  130. ' ============================================================================
  131. '
  132. SUB QuickSort (Low, High)
  133.     IF Low < High THEN
  134.  
  135.         ' Only two elements in this subdivision; swap them if they are out of
  136.         ' order, then end recursive calls:
  137.     
  138.         IF High - Low = 1 THEN
  139.             IF WordList(Low) > WordList(High) THEN
  140.                 SWAP WordList(Low), WordList(High)
  141.             END IF
  142.         ELSE
  143.  
  144.             ' Pick a pivot element at random, then move it to the end:
  145.  
  146.             RandIndex = RandInt%(Low, High)
  147.             SWAP WordList(High), WordList(RandIndex)
  148.             Partition$ = WordList(High)
  149.             DO
  150.             ' Move in from both sides towards the pivot element:
  151.             I = Low: J = High
  152.             DO WHILE (I < J) AND (WordList(I) <= Partition$)
  153.                 I = I + 1
  154.             LOOP
  155.             DO WHILE (J > I) AND (WordList(J) >= Partition$)
  156.                 J = J - 1
  157.             LOOP
  158.  
  159.             ' If we haven't reached the pivot element, it means that two
  160.             ' elements on either side are out of order, so swap them:
  161.             IF I < J THEN
  162.                 SWAP WordList(I), WordList(J)
  163.             END IF
  164.         LOOP WHILE I < J
  165.  
  166.             ' Move the pivot element back to its proper place in the array:
  167.  
  168.             SWAP WordList(I), WordList(High)
  169.  
  170.             ' Recursively call the QuickSort procedure (pass the smaller
  171.             ' subdivision first to use less stack space):
  172.             IF (I - Low) < (High - I) THEN
  173.                 QuickSort Low, I - 1
  174.                 QuickSort I + 1, High
  175.             ELSE
  176.                 QuickSort I + 1, High
  177.                 QuickSort Low, I - 1
  178.             END IF
  179.         END IF
  180.    END IF
  181. END SUB
  182.  
  183. ' =============================== RandInt% ===================================
  184. '   Returns a random integer greater than or equal to the Lower parameter
  185. '   and less than or equal to the Upper parameter.
  186. ' ============================================================================
  187. '
  188. FUNCTION RandInt% (Lower, Upper)
  189.    RandInt% = INT(RND * (Upper - Lower + 1)) + Lower
  190. END FUNCTION
  191.  
  192.